package com.twu.biblioteca.model;

import com.twu.biblioteca.model.item.exceptions.InexistantItemException;
import com.twu.biblioteca.model.exceptions.ItemAlreadyReservedException;
import com.twu.biblioteca.model.item.ItemFormatter;
import com.twu.biblioteca.model.item.ItemID;
import com.twu.biblioteca.model.item.ItemStatus;
import com.twu.biblioteca.model.item.books.Book;
import com.twu.biblioteca.model.item.books.BookFormatter;
import com.twu.biblioteca.model.item.movies.Movie;
import com.twu.biblioteca.model.item.movies.MovieFormatter;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: cschlumb
 * Date: 08/08/2013
 * Time: 11:20
 * To change this template use File | Settings | File Templates.
 */
public class LibraryCatalogue {

    private final Map<ItemID, Book> collectionOfBooks;
    private final Map<ItemID, Movie> collectionOfMovies;
    private final Map<ItemID, ItemStatus> catalogueStatus;

    public LibraryCatalogue() {
        collectionOfBooks = new HashMap<ItemID, Book>();
        collectionOfMovies = new HashMap<ItemID, Movie>();
        catalogueStatus = new HashMap<ItemID, ItemStatus>();
    }

    public int getNumberOfBooks() {
        return collectionOfBooks.size();
    }

    public int getNumberOfMovies() {
        return collectionOfMovies.size();
    }

    public ItemID addItem(Book book){
        ItemID itemID = ItemID.nextID();
        collectionOfBooks.put(itemID, book);
        catalogueStatus.put(itemID, ItemStatus.AVAILABLE);
        return itemID;
    }
    public ItemID addItem(Movie movie){
        ItemID itemID = ItemID.nextID();
        collectionOfMovies.put(itemID, movie);
        catalogueStatus.put(itemID, ItemStatus.AVAILABLE);
        return itemID;
    }

    public List<ItemID> addMultipleBooks(List<Book> collectionOfBooks) {
        List<ItemID> itemIDList = new ArrayList<ItemID>();

        for (Book item : collectionOfBooks){
            itemIDList.add(addItem(item));
        }

        return itemIDList;
    }

    public List<ItemID> addMultipleMovies(List<Movie> collectionOfMovies) {
        List<ItemID> itemIDList = new ArrayList<ItemID>();

        for (Movie item : collectionOfMovies){
            itemIDList.add(addItem(item));
        }

        return itemIDList;
    }

    public void clear() {
        collectionOfBooks.clear();
        collectionOfMovies.clear();
    }

    public void formatBookList(ItemFormatter formatter) {
        for (Map.Entry<ItemID, Book> e : collectionOfBooks.entrySet()){
            formatter.add(e.getKey(), e.getValue(), catalogueStatus.get(e.getKey()));
        }
    }

    public void formatMovieList(ItemFormatter formatter) {
        for (Map.Entry<ItemID, Movie> e : collectionOfMovies.entrySet()){
            formatter.add(e.getKey(), e.getValue(), catalogueStatus.get(e.getKey()));
        }
    }

    public ItemStatus getStatus(ItemID itemID) throws InexistantItemException {
        itemExistsPrecondition(itemID);

        return catalogueStatus.get(itemID);
    }

    public void reserve(ItemID id) throws InexistantItemException, ItemAlreadyReservedException {
        itemExistsPrecondition(id);

        if (catalogueStatus.get(id).equals(ItemStatus.RESERVED))
            throw new ItemAlreadyReservedException();

        catalogueStatus.put(id, ItemStatus.RESERVED);
    }

    private void itemExistsPrecondition(ItemID id) throws InexistantItemException {
        if ( ! collectionOfBooks.containsKey(id) && ! collectionOfMovies.containsKey(id))
            throw new InexistantItemException();
    }
}
